﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Pico.Platform;
using TMPro;
using UnityEngine;
using UnityEngine.Android;

[Serializable]
public class PatientData
{
    public string patientId;
    public string bloodPressureHigh;
    public string bloodPressureLow;
    public string heartRate;
    public string oxygenSaturation;
    public string respiratoryRate;
    public string eyebrowKeyword;
    public string eyeKeyword;
    public string complexionKeyword;
    public string errorMessage;
}

public class SpeechDemo : MonoBehaviour
{
    public TMP_Text textAsrResult;
    // 文件统计目标文件夹路径
    public string fileStatisticsFolderPath = "/storage/emulated/0/baocun/";

    private bool inited = false;
    private bool listening = true;

    // 当前结构化数据
    private PatientData currentInfo = new PatientData();

    // 状态标记
    private bool isValue = false;
    private bool firstLoadDone = false;

    void Start()
    {
        CoreService.Initialize();
        if (!Permission.HasUserAuthorizedPermission(Permission.Microphone))
            Permission.RequestUserPermission(Permission.Microphone);
        if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
            Permission.RequestUserPermission(Permission.ExternalStorageWrite);

        SpeechService.SetOnAsrResultCallback(msg =>
        {
            var m = msg.Data;
            Debug.Log($"text={m.Text} isFinal={m.IsFinalResult}");
            ProcessAsrResult(m.Text, m.IsFinalResult);
        });
        SpeechService.SetOnSpeechErrorCallback(msg =>
        {
            var m = msg.Data;
            Debug.Log($"SpeechError :{JsonConvert.SerializeObject(m)}");
        });

        StartCoroutine(DelayedInitAsrEngine());
    }

    private IEnumerator DelayedInitAsrEngine()
    {
        yield return new WaitForSeconds(2.0f);
        var res = SpeechService.InitAsrEngine();
        if (res != AsrEngineInitResult.Success)
        {
            Debug.Log($"Init ASR Engine failed :{res}");
            textAsrResult.SetText($"init failed {res}");
        }
        else
        {
            inited = true;
            Debug.Log("Init engine successfully.");
            // 首次加载历史数据并显示
            if (!firstLoadDone)
            {
                LoadLastPatientInfo();
                if (isValue)
                    textAsrResult.SetText(FormatPatientInfo(currentInfo));
                firstLoadDone = true;
            }
            // 启动连续识别
            StartCoroutine(ContinuousRecognitionRoutine());
        }
    }

    // 循环识别，规避 60s 限制
    IEnumerator ContinuousRecognitionRoutine()
    {
        while (listening)
        {
            Debug.Log("启动识别");
            SpeechService.StartAsr(false, true, 60);
            yield return new WaitForSeconds(60);
            Debug.Log("停止识别并重启");
            SpeechService.StopAsr();
            yield return new WaitForSeconds(0.5f);
        }
    }

    private void ProcessAsrResult(string text, bool isFinal)
    {
        if (text.Contains("伤员"))
        {
            string pid = ExtractPatientId(text);
            if (!string.IsNullOrEmpty(pid) && pid != currentInfo.patientId)
            {
                // 保存旧伤员数据
                SavePatientInfo();
                // 清空截图文件
                DeleteAllFilesInFolder(fileStatisticsFolderPath);

                // 更新新伤员
                currentInfo = new PatientData { patientId = pid };
                isValue = true;

                SpeechService.StopAsr();
                SpeechService.StartAsr(false, true, 60);
            }
        }

        if (isValue)
        {
            // 提取并更新结构化字段
            if (text.Contains("高压"))
                currentInfo.bloodPressureHigh = ConvertChineseToArabic(ExtractValue(text, "高压"));
            if (text.Contains("低压"))
                currentInfo.bloodPressureLow = ConvertChineseToArabic(ExtractValue(text, "低压"));
            if (text.Contains("心率"))
                currentInfo.heartRate = ConvertChineseToArabic(ExtractValue(text, "心率"));
            if (text.Contains("血氧"))
                currentInfo.oxygenSaturation = ConvertChineseToArabic(ExtractValue(text, "血氧"));
            if (text.Contains("呼吸频率"))
                currentInfo.respiratoryRate = ConvertChineseToArabic(ExtractValue(text, "呼吸频率"));

            // 实时显示
            textAsrResult.SetText(FormatPatientInfo(currentInfo));


            // 检测“保存”或“结束”命令
            if (text.Contains("保存"))
            {
                // 1) 保存
                SavePatientInfo();
                DeleteAllFilesInFolder(fileStatisticsFolderPath);

                // 2) 反馈
                textAsrResult.SetText("数据已保存，重新开始识别");

                // 3) 清空当前数据，不会再加载上一个伤员
                currentInfo = new PatientData();
                isValue = false;

                // 4) 重启 ASR 会话
                SpeechService.StopAsr();
                SpeechService.StartAsr(false, true, 60);
            }
            else if (text.Contains("结束"))
            {
                // 和“保存”类似，但结束整个识别流程
                SavePatientInfo();
                DeleteAllFilesInFolder(fileStatisticsFolderPath);

                textAsrResult.SetText("数据已保存，识别已结束");
                listening = false;
                SpeechService.StopAsr();
            }
        }
    }

    // 格式化展示文本
    private string FormatPatientInfo(PatientData info)
    {
        var sb = new StringBuilder();
        sb.AppendLine($"伤员编号：{info.patientId}");
        sb.AppendLine($"高压：{info.bloodPressureHigh}");
        sb.AppendLine($"低压：{info.bloodPressureLow}");
        sb.AppendLine($"心率：{info.heartRate}");
        sb.AppendLine($"血氧：{info.oxygenSaturation}");
        sb.AppendLine($"呼吸频率：{info.respiratoryRate}");
        sb.AppendLine();
        sb.AppendLine("【文件统计】");
        sb.AppendLine($"眉毛：{info.eyebrowKeyword}");
        sb.AppendLine($"睁眼：{info.eyeKeyword}");
        sb.AppendLine($"肤色：{info.complexionKeyword}");
        if (!string.IsNullOrEmpty(info.errorMessage))
            sb.AppendLine($"[错误] {info.errorMessage}");
        return sb.ToString();
    }

    private void SavePatientInfo()
    {
        if (!isValue || string.IsNullOrEmpty(currentInfo.patientId)) return;

        // 获取文件统计字段
        GetFileStatisticsSummary(fileStatisticsFolderPath,
            out currentInfo.eyebrowKeyword,
            out currentInfo.eyeKeyword,
            out currentInfo.complexionKeyword);

        string json = JsonConvert.SerializeObject(currentInfo, Formatting.Indented);
        string fileName = $"Patient_{currentInfo.patientId}_latest.json";
        string filePath = Path.Combine(Application.persistentDataPath, fileName);
        try
        {
            File.WriteAllText(filePath, json, Encoding.UTF8);
            Debug.Log($"[Save] JSON文件已保存：{filePath}");
            PlayerPrefs.SetString("LastPatientFile", filePath);
            PlayerPrefs.Save();
        }
        catch (Exception e)
        {
            Debug.LogError($"[Save] 保存失败：{e.Message}");
        }
    }

    private void LoadLastPatientInfo()
    {
        string lastPath = PlayerPrefs.GetString("LastPatientFile", "");
        if (!string.IsNullOrEmpty(lastPath) && File.Exists(lastPath))
        {
            try
            {
                string json = File.ReadAllText(lastPath, Encoding.UTF8);
                currentInfo = JsonConvert.DeserializeObject<PatientData>(json);
                currentInfo = currentInfo ?? new PatientData();
                isValue = !string.IsNullOrEmpty(currentInfo.patientId);
                Debug.Log($"[Load] 成功加载：{lastPath}");
            }
            catch (Exception ex)
            {
                Debug.LogError($"[Load] 解析 JSON 失败：{ex.Message}");
            }
        }
        else
        {
            Debug.LogWarning("[Load] 没有找到历史 JSON 文件");
        }
    }

    private void GetFileStatisticsSummary(string folderPath,
        out string eyebrow, out string eye, out string complexion)
    {
        eyebrow = "无"; eye = "无"; complexion = "无";
        if (!Directory.Exists(folderPath)) return;

        string[] eyebrowWords = { "眉毛" };
        string[] eyeWords = { "睁眼" };
        string[] complexionWords = { "红润", "偏红", "偏白", "苍白" };

        var ebCounts = eyebrowWords.ToDictionary(w => w, _ => 0);
        var eyCounts = eyeWords.ToDictionary(w => w, _ => 0);
        var cmCounts = complexionWords.ToDictionary(w => w, _ => 0);

        foreach (var file in Directory.GetFiles(folderPath, "*.txt"))
        {
            var content = File.ReadAllText(file, Encoding.UTF8);
            foreach (var w in eyebrowWords) ebCounts[w] += Regex.Matches(content, w).Count;
            foreach (var w in eyeWords) eyCounts[w] += Regex.Matches(content, w).Count;
            foreach (var w in complexionWords) cmCounts[w] += Regex.Matches(content, w).Count;
        }

        eyebrow = ebCounts.OrderByDescending(kv => kv.Value).First().Key;
        eye = eyCounts.OrderByDescending(kv => kv.Value).First().Key;
        complexion = cmCounts.OrderByDescending(kv => kv.Value).First().Key;
    }

    public void DeleteAllFilesInFolder(string folderPath)
    {
        if (!Directory.Exists(folderPath))
        {
            Debug.LogWarning($"路径不存在：{folderPath}");
            return;
        }
        foreach (var file in Directory.GetFiles(folderPath))
        {
            try { File.Delete(file); }
            catch (Exception e) { Debug.LogError($"删除失败 {file}：{e.Message}"); }
        }
    }

    private string ExtractValue(string text, string key)
    {
        int start = text.IndexOf(key) + key.Length;
        int end = start;
        while (end < text.Length && (NumStrs.ContainsKey(text[end]) || UnitStrs.ContainsKey(text[end]))) end++;
        return text.Substring(start, end - start).Trim();
    }

    private string ExtractPatientId(string text)
    {
        int s = text.IndexOf("伤员") + 2;
        int e = text.IndexOf("号", s);
        return (e > s) ? text.Substring(s, e - s).Trim() : string.Empty;
    }

    private static readonly Dictionary<char, int> NumStrs = new Dictionary<char, int>
    {
        {'零',0},{'一',1},{'二',2},{'三',3},{'四',4},{'五',5},{'六',6},{'七',7},{'八',8},{'九',9}
    };
    private static readonly Dictionary<char, int> UnitStrs = new Dictionary<char, int>
    {
        {'十',10},{'百',100},{'千',1000},{'万',10000},{'亿',100000000}
    };

    public static string ConvertChineseToArabic(string cn)
    {
        try { return ConvertToArabic(cn).ToString(); }
        catch { return "转换错误"; }
    }

    private static long ConvertToArabic(string cn)
    {
        long res = 0, section = 0, num = 0;
        foreach (var c in cn)
        {
            if (NumStrs.ContainsKey(c)) num = NumStrs[c];
            else if (UnitStrs.ContainsKey(c))
            {
                int v = UnitStrs[c];
                if (v >= 10000)
                {
                    section = (section + num) * v;
                    res += section;
                    section = 0;
                }
                else section += (num == 0 && v == 10 ? 1 : num) * v;
                num = 0;
            }
        }
        return res + section + num;
    }
}
